package com.ljw.spring.annotation.conf;

import com.ljw.spring.annotation.aop.MathCalculator;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @FileName ConfigOfAOP
 * @Description TODO AOP思想【切面编程，底层动态代理】： 指在程序运行期间动态地将某段代码切入到指定方法指定位置进行运行的编程
 *  1. 导入spring Aop模块依赖:spring-aspects
 *  2. 自定一个业务逻辑类（MathCalculator），在业务逻辑运行的时候将日志进行打印
 *  3. 自定义一个切面类（LogAspects），切面类里面的方法需要动态感知MathCalculator.div(int i,int j)方法运行到什么地步
 *  4. 给切面类的方法标注通知注解（表明切面类的方法何时何地开始执行）
 *      通知注解:
 *          前置通知注解@Before【切点表达式的方法执行前先执行切面类方法】、
 *          后置通知注解@After【切点表达式的方法执行完成后开始执行切面类方法，无论方法是否抛出异常】、
 *          返回通知注解@AfterReturning【切点表达式的方法执行成功（无异常），才开始执行切面类方法】、
 *          异常通知注解@AfterThrowing【切点表达式的方法抛出异常就执行切面类方法】
 *          环绕通知注解@Around【动态代理，手动推进目标方法运行（joinPoint.procced()】
 *  5. 将业务逻辑类和切面类都加入到IOC容器中：@Component或@Bean
 *  6. 告诉spring哪个类是切面类，在切面类上添加注解 @Aspect
 *  7. 在配置类上添加注解@EnableAspectJAutoProxy//开启基于注解的aop功能
 *
 *  切面类各个通知执行顺序，2种情况：
 *      1.正常运行无异常：前置通知==》目标方法==》后置通知==》返回通知
 *      2.运行有异常：前置通知==》目标方法==》后置通知==》异常通知
 *
 *  注解原理：AOP的拦截功能
 *  举例：@EnableAspectJAutoProxy注解：
 *      1. @EnableAspectJAutoProxy 给IOC容器注册一个组件AnnotationAwareAspectJAutoProxyCreator[后置处理器]
 *      2. IOC容器创建流程：
 *          （1）registerBeanPostProcessors(beanFactory)注册后置处理器，创建AnnotationAwareAspectJAutoProxyCreator
 *          （2）finishBeanFactoryInitialization(beanFactory)初始化剩下的单实例bean
 *                  a. 创建业务逻辑组件和切面组件
 *                  b. AnnotationAwareAspectJAutoProxyCreator拦截业务逻辑组件和切面组件的创建过程
 *                  c. 业务逻辑组件和切面组件创建完之后，判断组件是否需要增强
 *                      是：切面的通知方法，包装成增强器；给业务逻辑组件创建代理对象（CGLIB代理对象)
 *       3. 代理对象执行目标方法
 *          （1）CglibAopProxy.intercept()
 *                  a. 得到目标方法的拦截器链（增强器包装成拦截器）
 *                  b. 利用拦截器的链式机制依次进入每个拦截器执行
 *
 * @Author ljw
 * @Date 2021/2/3 13:41
 * @Version 1.0
 */
@Configuration
@EnableAspectJAutoProxy//开启切面自动代理功能
@ComponentScan(basePackages = {"com.ljw.spring.annotation.aop"})
public class ConfigOfAOP {

    /*@Bean
    public MathCalculator getMathCalculator(){
        return new MathCalculator();
    }*/

}
